﻿/*++
 * Copyright (c) DemeterSoft Corporation
 *
 * File Name:
 *     LoadingView.cs
 *     
 * Abstract:
 *     数据读取页面
 *
 * Revision History:
 *     09/08/2011    yliu
 *         创建文件
 * --*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Windows;
using System.Windows.Browser;
using SmartSpace.Silverlight;
using SmartSpace.Silverlight.Shell.ServiceRef;

namespace SmartSpace.Silverlight.Shell
{
    /// <summary>
    /// 数据读取页面
    /// </summary>
    public partial class LoadingView : SlView
    {
        /// <summary>
        /// 已加载的模块索引
        /// </summary>
        private int m_loadedModuleIndex;

        /// <summary>
        /// 已下载的模块索引
        /// </summary>
        private int m_downLoadedModuleIndex;

        /// <summary>
        /// 切换应用程序的时候，保存切换到的应用程序信息
        /// </summary>
        private SlApplication m_switchApplication;

        private List<SmartSpace.Silverlight.Shell.ServiceRef.Module> _modules;
        /// <summary>
        /// 需要加载的模块
        /// </summary>
        private Dictionary<Guid, SmartSpace.Silverlight.Shell.ServiceRef.Module> _neededModules;

        public LoadingView()
        {
            InitializeComponent();

            m_progressBar.Maximum = 1;
            m_progressBar.Minimum = 0;
        }

        public LoadingView(SlApplication switchApplication)
        {
            InitializeComponent();

            m_progressBar.Maximum = 1;
            m_progressBar.Minimum = 0;

            m_switchApplication = switchApplication;
        }

        /// <summary>
        /// 
        /// </summary>
        protected override void OnShown()
        {
            //m_storyboardLoading.RepeatBehavior = new System.Windows.Media.Animation.RepeatBehavior(1000);
            //m_storyboardLoading.Begin();

            m_loadedModuleIndex = 0;
            _neededModules = new Dictionary<Guid, SmartSpace.Silverlight.Shell.ServiceRef.Module>();

            LoadApplications();
        }

        protected override void OnHidden()
        {
            //m_storyboardLoading.Stop();
        }

        #region step-1 LoadApplication

        /// <summary>
        /// step-1
        /// 读取应用程序信息
        /// </summary>
        private void LoadApplications()
        {
            m_progressBar.Value = 0;
            m_textMessage.Text = "读取系统信息...";

            SlWebServiceSoapClient client = App.CreateSlWebServiceProxy();
            client.GetApplicationsCompleted += new EventHandler<GetApplicationsCompletedEventArgs>(OnGetApplicationsCompleted);
            client.GetApplicationsAsync(AppData.User.Account);
        }

        private void OnGetApplicationsCompleted(object sender, GetApplicationsCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("获取出错!");
            }
            else if (!e.Result.IsSuccess)
            {
                MessageBox.Show("获取失败!");
            }
            else
            {
                AppData.Applications = new List<SlApplication>();
                foreach (SmartSpace.Silverlight.Shell.ServiceRef.Application application in e.Result.Data)
                {
                    SlApplication slApplication = new SlApplication();
                    slApplication.ID = application.Id;
                    slApplication.Name = application.Name;
                    slApplication.ThemeId = application.ThemeId;
                    string url = string.Format("./_handlers/_private/get-image.ashx?id={0}",application.ImageId);
                    slApplication.IconUri = new Uri((App.Current as SlApp).Params.HostUrl, url);

                    AppData.Applications.Add(slApplication);
                }

                LoadDefaultApplication();
            }
        }

        #endregion

        #region step-2 LoadDefaultApplication
        private void LoadDefaultApplication()
        {
            if (m_switchApplication == null)
            {
                SlWebServiceSoapClient client = App.CreateSlWebServiceProxy();
                client.GetDefaultApplicationCompleted += new EventHandler<GetDefaultApplicationCompletedEventArgs>(client_GetDefaultApplicationCompleted);
                client.GetDefaultApplicationAsync(AppData.User.Account);
            }
            else
            {
                foreach (var item in AppData.Applications)
                {
                    if (item.ID == m_switchApplication.ID)
                    {
                        AppData.CurrentApplication = item;
                        break;
                    }
                }

                LoadTheme();
            }
        }

        void client_GetDefaultApplicationCompleted(object sender, GetDefaultApplicationCompletedEventArgs e)
        {
            if (e.Error == null && e.Result.IsSuccess)
            {
                foreach (var item in AppData.Applications)
                {
                    if (item.ID == e.Result.Data.Id)
                    {
                        AppData.CurrentApplication = item;
                        break;
                    }
                }
                LoadTheme();
            }
            else
            {
                MessageBox.Show("获取默认应用程序失败!");
            }
        }
        #endregion

        #region step-3 LoadTheme
        private void LoadTheme()
        {
            SlWebServiceSoapClient client = App.CreateSlWebServiceProxy();
            client.GetThemeCompleted += new EventHandler<GetThemeCompletedEventArgs>(client_GetThemeCompleted);
            client.GetThemeAsync(AppData.CurrentApplication.ThemeId);
        }

        void client_GetThemeCompleted(object sender, GetThemeCompletedEventArgs e)
        {
            if (e.Error == null && e.Result.IsSuccess)
            {
                AppData.CurrentApplication.ThemeName = e.Result.Data.Package;
                AppData.CurrentApplication.ThemeVersion = e.Result.Data.Version;
                // 读取导航
                LoadNavigations();
            }
        }
        #endregion

        #region step-4 LoadNavigations

        private void LoadNavigations()
        {
            m_progressBar.Value = 0.1;
            m_textMessage.Text = "读取导航...";

            SlWebServiceSoapClient client = App.CreateSlWebServiceProxy();
            client.GetNavigationsCompleted += new EventHandler<GetNavigationsCompletedEventArgs>(OnGetNavigationsCompleted);
            client.GetNavigationsAsync(AppData.CurrentApplication.ID, AppData.User.Account);
        }

        private void OnGetNavigationsCompleted(object sender, GetNavigationsCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("获取出错!");
            }
            else if (!e.Result.IsSuccess)
            {
                MessageBox.Show("获取失败!");
            }
            else
            {
                _neededModules = new Dictionary<Guid, SmartSpace.Silverlight.Shell.ServiceRef.Module>();

                AppData.Navigations = new List<SlNavigation>();
                foreach (Navigation richNavigation in e.Result.Data)
                {
                    AppData.Navigations.Add(ConvertNavigation(richNavigation));
                }

                LoadShortcuts();
            }
        }

        private SlNavigation ConvertNavigation(Navigation richNavigation)
        {
            if (richNavigation.ModuleId != null && richNavigation.ModuleId.Value != Guid.Empty)
            {
                bool isExist = false;
                foreach (var key in _neededModules.Keys)
                {
                    if (key == richNavigation.ModuleId.Value)
                    {
                        isExist = true;
                        break;
                    }
                }
                if (!isExist)
                {
                    _neededModules.Add(richNavigation.ModuleId.Value, null);
                }
            }

            SlNavigation navigation = new SlNavigation();
            navigation.ID = richNavigation.Id;
            navigation.Name = richNavigation.Caption;
            navigation.Order = richNavigation.SortIndex;
            //navigation.IconID = richNavigation.IconID;
            //navigation.IconPath = richNavigation.IconPath;

            if (richNavigation.ModuleId!=null && richNavigation.ViewId!=null
                && richNavigation.ModuleId.Value != Guid.Empty
                && richNavigation.ViewId.Value != Guid.Empty)
            {
                navigation.View = new SlNavigateView(richNavigation.ModuleId.Value, richNavigation.ViewId.Value);
                navigation.View.ViewArguments = richNavigation.Arguments;
            }

            foreach (Navigation child in richNavigation.Children)
            {
                navigation.Children.Add(ConvertNavigation(child));
            }

            if (richNavigation.IsDefault)
            {
                AppData.DefaultNavigation = navigation;
            }

            //if (navigation.ID == AppData.CurrentApplication.DefaultNavigationID)
            //{
            //    AppData.DefaultView = navigation.View;
            //    AppData.DefaultViewName = navigation.Name;
            //}

            return navigation;
        }

        #endregion

        #region step-5 LoadShortcuts

        private void LoadShortcuts()
        {
            m_progressBar.Value = 0.2;
            m_textMessage.Text = "读取快捷方式...";

            SlWebServiceSoapClient client = App.CreateSlWebServiceProxy();
            client.GetShortcutsCompleted += new EventHandler<GetShortcutsCompletedEventArgs>(client_GetShortcutsCompleted);
            client.GetShortcutsAsync(AppData.CurrentApplication.ID, AppData.User.Account);
        }

        void client_GetShortcutsCompleted(object sender, GetShortcutsCompletedEventArgs e)
        {
            if (e.Result.IsSuccess)
            {
                AppData.Shortcuts = new List<SlShortcut>();

                foreach (Shortcut shortcutModel in e.Result.Data)
                {
                    SlShortcut shortcut = new SlShortcut();
                    shortcut.ID = shortcutModel.Id;
                    shortcut.Name = shortcutModel.Caption;
                    shortcut.Order = shortcutModel.SortIndex;
                    //shortcut.IconID = shortcutModel.IconID;
                    //shortcut.IconPath = shortcutModel.IconPath;
                    Stack<SlNavigation> stack = new Stack<SlNavigation>();
                    if (shortcutModel.NavigationId != Guid.Empty)
                    {
                        foreach (var navigation in AppData.Navigations)
                        {
                            stack.Push(navigation);
                        }

                        while (stack.Count > 0)
                        {
                            SlNavigation item = stack.Pop();

                            if (item.ID == shortcutModel.NavigationId)
                            {
                                shortcut.View = item.View;
                                break;
                            }

                            foreach (var subItem in item.Children)
                            {
                                stack.Push(subItem);
                            }
                        }
                    }
                    //if (shortcutModel.View != null)
                    //{
                    //    shortcut.View = new SlNavigateView(shortcutModel.View.ModuleID, shortcutModel.View.ID);
                    //    shortcut.View.ViewArguments = shortcutModel.ViewArguments;
                    //}

                    //if (shortcut.ID == AppData.CurrentApplication.DefaultNavigationID)
                    //{
                    //    AppData.DefaultView = shortcut.View;
                    //    AppData.DefaultViewName = shortcut.Name;
                    //}

                    AppData.Shortcuts.Add(shortcut);
                }

                m_progressBar.Value = 0.3;
                m_textMessage.Text = "初始化可用的导航...";

                LoadModules();
            }
        }

        #endregion

        #region step-6 LoadModules

        private void LoadModules()
        {
            m_progressBar.Value = 0.4;
            m_textMessage.Text = "读取模块信息...";

            SlWebServiceSoapClient client = App.CreateSlWebServiceProxy();
            client.GetModulesCompleted += new EventHandler<GetModulesCompletedEventArgs>(OnGetModulesCompleted);
            client.GetModulesAsync(AppData.CurrentApplication.ID);
        }

        private void OnGetModulesCompleted(object sender, GetModulesCompletedEventArgs e)
        {
            if (e.Result.IsSuccess)
            {
                this._modules = e.Result.Data.ToList();

                foreach (var module in e.Result.Data)
                {
                    foreach (Guid  key in _neededModules.Keys)
                    {
                        if (key == module.Id)
                        {
                            _neededModules[key] = module;
                            break;
                        }
                    }
                }
                DownLoadCommonModule();
            }
            else
            {
                MessageBox.Show("读取模块信息失败!");
            }
        }

        #endregion

        #region step-7 加载公共模块

        private void DownLoadCommonModule()
        {
            WebClient webCommonClient = new WebClient();
            webCommonClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webCommonClient_OpenReadCompleted);
            webCommonClient.OpenReadAsync(new Uri("SupervisionMgt.Basic.dll", UriKind.Relative));
        }

        void webCommonClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                AssemblyPart assemblyPart = new AssemblyPart();
                try
                {
                    Assembly assembly = assemblyPart.Load(e.Result);
                    //AppDomain.CurrentDomain.ass
                }
                catch
                {
                }
            }
            DownloadModules();
        }

        #endregion

        #region step-8 DownloadModules

        private void DownloadModules()
        {
            m_progressBar.Value = 0.5;
            m_textMessage.Text = "加载模块...";
            m_downLoadedModuleIndex = 0;

            if (m_downLoadedModuleIndex < this._neededModules.Keys.Count)
            {
                SmartSpace.Silverlight.Shell.ServiceRef.Module module = _neededModules[_neededModules.Keys.ToList()[m_downLoadedModuleIndex]];
                // 加载模块
                string url = string.Format(
                    "./Handlers/LoadModule.ashx?id={0}&version={1}",
                    module.Id,
                    module.Version);
                WebClient webClient = new WebClient();
                webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(OnDownloadModuleCompleted);
                webClient.OpenReadAsync(new Uri((App.Current as SlApp).Params.AppUrl, url));
            }
            else
            {
                // 没有需要加载的模块
                DownloadTheme();
            }
        }

        private void OnDownloadModuleCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            SmartSpace.Silverlight.Shell.ServiceRef.Module appModule = _neededModules[_neededModules.Keys.ToList()[m_downLoadedModuleIndex]];
            AssemblyPart assemblyPart = new AssemblyPart();
            try
            {
                Assembly assembly = assemblyPart.Load(e.Result);
                //AppData.ModuleAssemblies[appModule.Id] = assembly;
                // 创建模块对象
                // 初始化模块对象
                object moduleInstance = assembly.CreateInstance(appModule.Name);
                if (moduleInstance != null)
                {
                    SmartSpace.Silverlight.AppModule appModuleInstance = (SmartSpace.Silverlight.AppModule)moduleInstance;
                    appModuleInstance.LoadSettings(this.ParseArguments(appModule.Settings));
                    AppModuleManager.RegisterModule(appModuleInstance);
                }
                else
                {
                    MessageBox.Show("加载模块" + appModule.Name + "出错!");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载模块" + appModule.Name + "出错!" + Environment.NewLine
                    + ex.Message);
            }
            m_downLoadedModuleIndex++;
            if (m_downLoadedModuleIndex < _neededModules.Keys.Count)
            {
                // 加载模块
                SmartSpace.Silverlight.Shell.ServiceRef.Module module = _neededModules[_neededModules.Keys.ToList()[m_downLoadedModuleIndex]];
                // 加载模块
                string url = string.Format(
                    "./Handlers/LoadModule.ashx?id={0}&version={1}",
                    module.Id,
                    module.Version);
                WebClient webClient = new WebClient();
                webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(OnDownloadModuleCompleted);
                webClient.OpenReadAsync(new Uri((App.Current as SlApp).Params.AppUrl, url));
            }
            else
            {
                DownloadTheme();
            }
        }

        #endregion

        #region step-9 downloadTheme
        private void DownloadTheme()
        {
            m_progressBar.Value = 0.9;
            m_textMessage.Text = "读取主题...";

            string url = string.Format(
                "./Handlers/LoadTheme.ashx?id={0}&version={1}", 
                AppData.CurrentApplication.ThemeId, 
                AppData.CurrentApplication.ThemeVersion);
            WebClient webClient = new WebClient();
            webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
            webClient.OpenReadAsync(new Uri((App.Current as SlApp).Params.AppUrl, url));
        }

        void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            AssemblyPart assemblyPart = new AssemblyPart();
            Assembly assembly = null;

            try
            {
                assembly = assemblyPart.Load(e.Result);
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载主题包失败");
                // MessageBox.Show(ex.Message, "加载主题包失败", MessageBoxButton.OK);
                RootPage.Instance.SwitchView(new ErrorView(ex));
                return;
            }

            if (assembly != null)
            {
                Type[] types = assembly.GetTypes();

                ITheme theme = null;
                foreach (Type type in types)
                {
                    if (type.GetInterfaces().Contains(typeof(ITheme)))
                    {
                        object themeObj = assembly.CreateInstance(type.FullName);
                        if (themeObj != null)
                        {
                            theme = (ITheme)themeObj;
                            break;
                        }
                    }
                }
                if (theme != null)
                {
                    ThemeManager.Load(theme);

                    System.Windows.Application.Current.Resources.MergedDictionaries.Clear();
                    IEnumerable<ResourceDictionary> resources = theme.GetResourceDictionaries();
                    foreach (ResourceDictionary resource in resources)
                    {
                        System.Windows.Application.Current.Resources.MergedDictionaries.Add(resource);
                    }

                    IMainPanel mainPanel = theme.GetMainPanel();

                    mainPanel.GetHeaderPanel().Navigating += new NavigatingEventHandler(LoadingView_Navigating);

                    mainPanel.GetHeaderPanel().Initiate(AppData.Shortcuts, AppData.Applications, AppData.CurrentApplication, AppData.User);
                    mainPanel.GetHeaderPanel().Logoff += new LogoffEventHandler(LoadingView_Logoff);
                    mainPanel.GetHeaderPanel().EnterManagement += new EventHandler(LoadingView_EnterManagement);
                    mainPanel.GetHeaderPanel().ChangeApp += new ChangeAppEventHandler(LoadingView_ChangeApp);

                    mainPanel.GetNavigatePanel().Navigating += new NavigatingEventHandler(LoadingView_Navigating);
                    mainPanel.GetNavigatePanel().LoadNavigations(AppData.Navigations, AppData.Shortcuts);

                    m_progressBar.Value = 1;

                    RootPage.Instance.SwitchView(theme.GetMainPanel().GetContentView());

                    // 切换到默认导航
                    if (AppData.DefaultNavigation != null)
                    {
                        LoadingView_Navigating(this, new NavigatingEventArgs(AppData.DefaultNavigation.Name, AppData.DefaultNavigation.View));
                    }
                }
                else
                {
                    MessageBox.Show("加载主题失败!");

                    RootPage.Instance.SwitchView(new ErrorView());
                }
            }
        }
        #endregion

        void LoadingView_ChangeApp(object sender, ChangeAppEventArgs e)
        {
            RootPage.Instance.SwitchView(new LoadingView(e.App));
        }

        void LoadingView_EnterManagement(object sender, EventArgs e)
        {
            HtmlPage.Window.Navigate(new Uri((App.Current as SlApp).Params.AppUrl + "manager.aspx", UriKind.RelativeOrAbsolute));
        }

        void LoadingView_Navigating(object sender, NavigatingEventArgs e)
        {
            if (e.View != null)
            {
                try
                {
                    ModuleView viewModel = GetView(e.View.ModuleID, e.View.ViewID);
                    object obj = SmartSpace.Silverlight.AppModuleManager.GetModule(e.View.ModuleID).CreateView(viewModel.Name);
                    SlView view = (SlView)obj;
                    view.Authentication = new Authentication();
                    view.Authentication.Account = AppData.User.Account;
                    view.Authentication.Name = AppData.User.Name;

                    if (view is AppView)
                    {
                        AppView appView = view as AppView;

                        appView.SetCaption(e.NavigationCaption);

                        #region 设置初始化参数
                        if (!string.IsNullOrEmpty(e.View.ViewArguments))
                        {
                            Dictionary<string, object> viewArguments = new Dictionary<string, object>();
                            string[] argArray = e.View.ViewArguments.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string arg in argArray)
                            {
                                string[] argData = arg.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                                if (argData.Length == 2)
                                {
                                    string argKey = argData[0].Trim();
                                    string argValue = argData[1].Trim();

                                    if (!viewArguments.ContainsKey(argKey))
                                    {
                                        viewArguments.Add(argKey, argValue);
                                    }
                                }
                            }
                            appView.SetArguments(viewArguments);
                        }

                        #endregion

                        #region 检查授权

                        List<Guid> authorizedActions = new List<Guid>();
                        appView.SetAuthorizedActions(authorizedActions);

                        #endregion
                    }
                    ThemeManager.CurrentTheme.GetMainPanel().GetWorkAreaPanel().Switch(view);
                }
                catch (Exception exception)
                {
                    string message = "创建视图:" + e.View.ViewID.ToString() + ",模块:" + e.View.ModuleID.ToString();
                    ThemeManager.CurrentTheme.GetMainPanel().GetWorkAreaPanel().Switch(new ErrorView(message));
                }
                return;
            }
        }

        void LoadingView_Logoff(object sender, LogoffEventArgs e)
        {
            SlWebServiceSoapClient client = App.CreateSlWebServiceProxy();
            client.SignOutCompleted += new EventHandler<SignOutCompletedEventArgs>(client_SignOutCompleted);
            client.SignOutAsync();
        }

        void client_SignOutCompleted(object sender, SignOutCompletedEventArgs e)
        {
            if (e.Result.IsSuccess)
            {
                HtmlPage.Window.Navigate(new Uri((App.Current as SlApp).Params.HostUrl + "Login.aspx"));
                //HtmlPage.Window.Navigate(new Uri((App.Current as SlApp).Params.AppUrl + "KeyDefault.aspx"));
                //RootPage.Instance.SwitchView(new LoginView());
            }
            else
            {
                MessageBox.Show(e.Result.Message);
            }
        }

        private Dictionary<string, object> ParseArguments(string arguments)
        {
            Dictionary<string, object> viewArguments = new Dictionary<string, object>();
            if (string.IsNullOrEmpty(arguments))
            {
                return viewArguments;
            }
            string[] argArray = arguments.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string arg in argArray)
            {
                string[] argData = arg.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                if (argData.Length == 2)
                {
                    string argKey = argData[0].Trim();
                    string argValue = argData[1].Trim();

                    if (!viewArguments.ContainsKey(argKey))
                    {
                        viewArguments.Add(argKey, argValue);
                    }
                }
            }

            return viewArguments;
        }

        public ModuleView GetView(Guid moduleId, Guid viewId)
        {
            foreach (var key in this._neededModules.Keys)
            {
                if (key == moduleId)
                {
                    SmartSpace.Silverlight.Shell.ServiceRef.Module module = this._neededModules[key];
                    foreach (ModuleView view in module.Views)
                    {
                        if (view.Id == viewId)
                        {
                            return view;
                        }
                    }
                }
            }
            return null;
        }
    }
}
